compio_driver\sys\pal\windows/
mod.rs1use std::{fmt, io, ptr, task::Poll};
2
3pub use windows_sys::Win32::Networking::WinSock::CMSGHDR as CmsgHeader;
4use windows_sys::{
5 Win32::{
6 Foundation::{
7 ERROR_BROKEN_PIPE, ERROR_HANDLE_EOF, ERROR_IO_INCOMPLETE, ERROR_IO_PENDING,
8 ERROR_MORE_DATA, ERROR_NETNAME_DELETED, ERROR_NO_DATA, ERROR_NOT_FOUND,
9 ERROR_PIPE_CONNECTED, ERROR_PIPE_NOT_CONNECTED, GetLastError,
10 },
11 Networking::WinSock::{SIO_GET_EXTENSION_FUNCTION_POINTER, WSAIoctl},
12 System::IO::{CancelIoEx, OVERLAPPED},
13 },
14 core::GUID,
15};
16
17use crate::syscall;
18
19mod_use::mod_use![fd];
20
21pub mod reexport {
22 pub use super::Overlapped;
23}
24
25#[repr(C)]
27pub struct Overlapped {
28 pub base: OVERLAPPED,
30 pub driver: RawFd,
32}
33
34impl fmt::Debug for Overlapped {
35 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36 f.debug_struct("Overlapped")
37 .field("base", &"OVERLAPPED")
38 .field("driver", &self.driver)
39 .finish()
40 }
41}
42
43impl Overlapped {
44 pub(crate) fn new(driver: RawFd) -> Self {
45 Self {
46 base: unsafe { std::mem::zeroed() },
47 driver,
48 }
49 }
50}
51
52unsafe impl Send for Overlapped {}
54unsafe impl Sync for Overlapped {}
55
56#[inline]
57pub fn winapi_result(transferred: u32) -> Poll<io::Result<usize>> {
58 let error = unsafe { GetLastError() };
59 assert_ne!(error, 0);
60 match error {
61 ERROR_IO_PENDING => Poll::Pending,
62 ERROR_IO_INCOMPLETE
63 | ERROR_NETNAME_DELETED
64 | ERROR_HANDLE_EOF
65 | ERROR_BROKEN_PIPE
66 | ERROR_PIPE_CONNECTED
67 | ERROR_PIPE_NOT_CONNECTED
68 | ERROR_NO_DATA
69 | ERROR_MORE_DATA => Poll::Ready(Ok(transferred as _)),
70 _ => Poll::Ready(Err(io::Error::from_raw_os_error(error as _))),
71 }
72}
73
74#[inline]
75pub fn win32_result(res: i32, transferred: u32) -> Poll<io::Result<usize>> {
76 if res == 0 {
77 winapi_result(transferred)
78 } else {
79 Poll::Ready(Ok(transferred as _))
80 }
81}
82
83#[inline]
84pub fn winsock_result(res: i32, transferred: u32) -> Poll<io::Result<usize>> {
85 if res != 0 {
86 winapi_result(transferred)
87 } else {
88 Poll::Ready(Ok(transferred as _))
89 }
90}
91
92#[inline]
93pub fn cancel(handle: RawFd, optr: *mut OVERLAPPED) -> io::Result<()> {
94 match syscall!(BOOL, CancelIoEx(handle as _, optr)) {
95 Ok(_) => Ok(()),
96 Err(e) => {
97 if e.raw_os_error() == Some(ERROR_NOT_FOUND as _) {
98 Ok(())
99 } else {
100 Err(e)
101 }
102 }
103 }
104}
105
106pub fn get_wsa_fn<F>(handle: RawFd, fguid: GUID) -> io::Result<Option<F>> {
107 let mut fptr = None;
108 let mut returned = 0;
109 syscall!(
110 SOCKET,
111 WSAIoctl(
112 handle as _,
113 SIO_GET_EXTENSION_FUNCTION_POINTER,
114 std::ptr::addr_of!(fguid).cast(),
115 std::mem::size_of_val(&fguid) as _,
116 std::ptr::addr_of_mut!(fptr).cast(),
117 std::mem::size_of::<F>() as _,
118 &mut returned,
119 ptr::null_mut(),
120 None,
121 )
122 )?;
123 Ok(fptr)
124}